home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-19 / gpt32src.zip / GNUPLOT_.C < prev    next >
C/C++ Source or Header  |  1992-05-05  |  19KB  |  585 lines

  1. #ifndef lint
  2. static char *RCSid = "$Id: gnuplot_x11.c,v 3.26 92/03/24 22:35:52 woo Exp Locker: woo $";
  3. #endif
  4.  
  5. /*-----------------------------------------------------------------------------
  6.  *   gnuplot_x11 - X11 outboard terminal driver for gnuplot 3
  7.  *
  8.  *   Requires installation of companion inboard x11 driver in gnuplot/term.c
  9.  *
  10.  *   Acknowledgements: 
  11.  *      Chris Peterson (MIT)
  12.  *      Dana Chee (Bellcore) 
  13.  *      Arthur Smith (Cornell)
  14.  *      Hendri Hondorp (University of Twente, The Netherlands)
  15.  *      Bill Kucharski (Solbourne)
  16.  *      Charlie Kline (University of Illinois)
  17.  *      O'Reilly & Associates: X Window System - Volumes 1 & 2
  18.  *
  19.  *   This code is provided as is and with no warranties of any kind.
  20.  *       
  21.  *   Ed Kubaitis (ejk@uiuc.edu)
  22.  *   Computing & Communications Services Office 
  23.  *   University of Illinois, Urbana
  24.  *---------------------------------------------------------------------------*/
  25.  
  26. #include <X11/Xos.h>
  27. #include <X11/Xlib.h>
  28. #include <X11/Xutil.h>
  29. #include <X11/Xatom.h>
  30. #include <X11/Xresource.h>
  31.  
  32. #include <stdio.h>
  33. #include <signal.h>
  34.  
  35. #ifndef FD_SET
  36. #ifndef OLD_SELECT
  37. #include <sys/select.h>
  38. #else   /* OLD_SELECT */
  39. #define FD_SET(n, p)    ((p)->fds_bits[0] |= (1 << ((n) % 32)))
  40. #define FD_CLR(n, p)    ((p)->fds_bits[0] &= ~(1 << ((n) % 32)))
  41. #define FD_ISSET(n, p)  ((p)->fds_bits[0] & (1 << ((n) % 32)))
  42. #define FD_ZERO(p)      bzero((char *)(p), sizeof(*(p)))
  43. #endif  /* OLD_SELECT */
  44. #endif  /* FD_SET */
  45.  
  46. #include <errno.h>
  47. extern int errno;
  48.  
  49. #define FallbackFont "fixed"
  50. #define Ncolors 13
  51. unsigned long colors[Ncolors];
  52.  
  53. char dashes[10][5] = { {0}, {1,6,0}, 
  54.    {0}, {4,2,0}, {1,3,0}, {4,4,0}, {1,5,0}, {4,4,4,1,0}, {4,2,0}, {1,3,0}
  55.    };
  56.  
  57. Display *dpy; int scr; Window win, root;
  58. Visual *vis; GC gc = (GC)0; Pixmap pixmap; XFontStruct *font;
  59. unsigned int W = 640, H = 450; int D, gX = 100, gY = 100;
  60.  
  61. Bool Mono = 0, Gray = 0, Rv = 0, Clear = 0;
  62. char Name[64] = "gnuplot";
  63. char Class[64] = "Gnuplot";
  64.  
  65. int cx=0, cy=0, vchar, nc = 0, ncalloc = 0;
  66. double xscale, yscale;
  67. #define X(x) (int) (x * xscale)
  68. #define Y(y) (int) ((4095-y) * yscale)
  69. enum JUSTIFY { LEFT, CENTRE, RIGHT } jmode;
  70.  
  71. #define Nbuf 1024
  72. char buf[Nbuf], **commands = (char **)0;
  73.  
  74. FILE *X11_ipc = stdin;
  75. char X11_ipcpath[32];
  76.  
  77.  
  78. /*-----------------------------------------------------------------------------
  79.  *   main program 
  80.  *---------------------------------------------------------------------------*/
  81.  
  82. main(argc, argv) int argc; char *argv[]; {
  83.  
  84.    preset(argc, argv);
  85.    mainloop();
  86.    exit(0);
  87.  
  88.    }
  89.  
  90. /*-----------------------------------------------------------------------------
  91.  *   mainloop - process X events and input from gnuplot
  92.  *
  93.  *   On systems with a fully implemented select(), select is used (without
  94.  *   timeout) to sense both input from the X server network connection and
  95.  *   pipe input from gnuplot. On platforms with an incomplete or faulty 
  96.  *   select(), select (with timeout) is used for the server, and a temporary 
  97.  *   file rather than a pipe is used for gnuplot input.
  98.  *---------------------------------------------------------------------------*/
  99.  
  100. mainloop() {
  101.    int nf, nfds, cn = ConnectionNumber(dpy), in = fileno(X11_ipc);
  102.    struct timeval timeout, *timer = (struct timeval *)0;
  103.    fd_set rset, tset;
  104.    unsigned long all = 0xffffffff;
  105.    XEvent xe;
  106.  
  107.    FD_ZERO(&rset);
  108.    FD_SET(cn, &rset);
  109.  
  110. #ifndef CRIPPLED_SELECT
  111.    FD_SET(in, &rset);
  112.    nfds = (cn > in) ? cn + 1 : in + 1;
  113. #else  /* CRIPPLED_SELECT */
  114.    timeout.tv_sec = 1;
  115.    timeout.tv_usec = 0;
  116.    timer = &timeout;
  117.    sprintf(X11_ipcpath, "/tmp/Gnuplot_%d", getppid());
  118.    nfds = cn + 1;
  119. #endif /* CRIPPLED_SELECT */
  120.  
  121.    while(1) {
  122.       tset = rset;
  123.       nf = select(nfds, &tset, (fd_set *)0, (fd_set *)0, timer);
  124.       if (nf < 0) {
  125.      if (errno == EINTR) continue;
  126.      fprintf(stderr, "gnuplot: select failed. errno:%d\n", errno);
  127.      exit(1);
  128.      }
  129.       nf > 0 && XNoOp(dpy);
  130.       if (FD_ISSET(cn, &tset)) {
  131.      while (XCheckMaskEvent(dpy, all, &xe)) {
  132.         (xe.type == ConfigureNotify)  && resize(&xe); 
  133.         }
  134.      }
  135. #ifndef CRIPPLED_SELECT
  136.       FD_ISSET(in, &tset) && accept();
  137. #else  /* CRIPPLED_SELECT */
  138.       if ((X11_ipc = fopen(X11_ipcpath, "r"))) {
  139.      unlink(X11_ipcpath);
  140.      accept();
  141.      fclose(X11_ipc);
  142.      }
  143. #endif /* CRIPPLED_SELECT */
  144.       }
  145.    }
  146.  
  147. /*-----------------------------------------------------------------------------
  148.  *   accept - accept & record new plot from gnuplot inboard X11 driver
  149.  *---------------------------------------------------------------------------*/
  150.  
  151. accept() {
  152.  
  153.    while (fgets(buf, Nbuf, X11_ipc)) {
  154.      if (*buf == 'G') {                           /* enter graphics mode */
  155.      if (commands) {
  156.         int n; for (n=0; n<nc; n++) free(commands[n]);
  157.         free(commands);
  158.         }
  159.      commands = (char **)0; nc = ncalloc = 0;
  160.          }
  161.       else if (*buf == 'E') { display(); break; } /* leave graphics mode */
  162.       else if (*buf == 'R') { exit(0); }          /* leave X11/x11 mode  */
  163.       else {                                      /* record command      */
  164.      char *p;
  165.      if (nc >= ncalloc) {
  166.         ncalloc = ncalloc*2 + 1;
  167.         commands = (commands)
  168.            ? (char **)realloc(commands, ncalloc * sizeof(char *))
  169.            : (char **)malloc(sizeof(char *));
  170.         }
  171.      p = (char *)malloc((unsigned)strlen(buf)+1);
  172.      if (!commands || !p) {
  173.         fprintf(stderr, "gnuplot: can't get memory. X11 aborted.\n");
  174.         exit(1);
  175.         }
  176.      commands[nc++] = strcpy(p, buf);
  177.      }
  178.       }
  179.    if (feof(X11_ipc) || ferror(X11_ipc)) exit(1);
  180.    }
  181.  
  182. /*-----------------------------------------------------------------------------
  183.  *   display - display last plot from gnuplot inboard X11 driver
  184.  *---------------------------------------------------------------------------*/
  185.  
  186. display() {
  187.    int n, x, y, sw, sl, lt, width, type;
  188.    char *buf, *str;
  189.  
  190.    if (!nc) return;
  191.  
  192.    /* set scaling factor between internal driver & window geometry */
  193.    xscale = (double)W / 4096.;  yscale = (double)H / 4096.;  
  194.  
  195.    /* create new pixmap & GC */
  196.    if (gc) { XFreeGC(dpy, gc); XFreePixmap(dpy, pixmap); }
  197.    pixmap = XCreatePixmap(dpy, root, W, H, D);
  198.    gc = XCreateGC(dpy, pixmap, 0, (XGCValues *)0);
  199.    XSetFont(dpy, gc, font->fid);
  200.  
  201.    /* set pixmap background */
  202.    XSetForeground(dpy, gc, colors[0]);
  203.    XFillRectangle(dpy, pixmap, gc, 0, 0, W, H);
  204.    XSetBackground(dpy, gc, colors[0]);
  205.  
  206.    /* set new pixmap as window background */
  207.    XSetWindowBackgroundPixmap(dpy, win, pixmap);
  208.  
  209.    /* momentarily clear the window first if requested */
  210.    if (Clear) {
  211.       XClearWindow(dpy, win);
  212.       XFlush(dpy);
  213.       }
  214.  
  215.    /* loop over accumulated commands from inboard driver */
  216.    for (n=0; n<nc; n++) {
  217.       buf = commands[n];
  218.  
  219.       /*   X11_vector(x,y) - draw vector  */
  220.       if (*buf == 'V') { 
  221.      sscanf(buf, "V%4d%4d", &x, &y);  
  222.      XDrawLine(dpy, pixmap, gc, X(cx), Y(cy), X(x), Y(y));
  223.      cx = x; cy = y;
  224.      }
  225.  
  226.       /*   X11_move(x,y) - move  */
  227.       else if (*buf == 'M') 
  228.      sscanf(buf, "M%4d%4d", &cx, &cy);  
  229.  
  230.       /*   X11_put_text(x,y,str) - draw text   */
  231.       else if (*buf == 'T') { 
  232.      sscanf(buf, "T%4d%4d", &x, &y);  
  233.      str = buf + 9; sl = strlen(str) - 1;
  234.      sw = XTextWidth(font, str, sl);
  235.      switch(jmode) {
  236.         case LEFT:   sw = 0;     break;
  237.         case CENTRE: sw = -sw/2; break;
  238.         case RIGHT:  sw = -sw;   break;
  239.         }
  240.      XSetForeground(dpy, gc, colors[2]);
  241.      XDrawString(dpy, pixmap, gc, X(x)+sw, Y(y)+vchar/3, str, sl);
  242.      XSetForeground(dpy, gc, colors[lt+3]);
  243.      }
  244.  
  245.       /*   X11_justify_text(mode) - set text justification mode  */
  246.       else if (*buf == 'J') 
  247.      sscanf(buf, "J%4d", &jmode);
  248.  
  249.       /*   X11_linetype(type) - set line type  */
  250.       else if (*buf == 'L') { 
  251.      sscanf(buf, "L%4d", <);
  252.      lt = (lt%8)+2;
  253.      width = (lt == 0) ? 2 : 0;
  254.      if (!Mono) {
  255.         if (lt != 1) 
  256.            type = LineSolid;
  257.         else {
  258.            type = LineOnOffDash;
  259.            XSetDashes(dpy, gc, 0, dashes[lt], strlen(dashes[lt]));
  260.            }
  261.         XSetForeground(dpy, gc, colors[lt+3]);
  262.         }
  263.      else {
  264.         type  = (lt == 0 || lt == 2) ? LineSolid : LineOnOffDash;
  265.         if (dashes[lt][0])
  266.            XSetDashes(dpy, gc, 0, dashes[lt], strlen(dashes[lt]));
  267.         }
  268.      XSetLineAttributes( dpy,gc, width, type, CapButt, JoinBevel);
  269.      }
  270.       }
  271.  
  272.    /* trigger exposure of background pixmap */
  273.    XClearWindow(dpy,win);
  274.    XFlush(dpy);
  275.    }
  276.  
  277. /*-----------------------------------------------------------------------------
  278.  *   resize - rescale last plot if window resized
  279.  *---------------------------------------------------------------------------*/
  280.  
  281. Bool init = True;
  282.  
  283. resize(xce) XConfigureEvent *xce; {
  284.    if (!init || xce->width != W || xce->height != H) {
  285.       W = xce->width; H = xce->height;
  286.       display();
  287.       init = True;
  288.       }
  289.    }
  290.  
  291.  
  292. /*-----------------------------------------------------------------------------
  293.  *   preset - determine options, open display, create window
  294.  *---------------------------------------------------------------------------*/
  295.  
  296. #define On(v) ( !strcmp(v,"on") || !strcmp(v,"true") || \
  297.         !strcmp(v,"On") || !strcmp(v,"True") )
  298.  
  299. #define AppDefDir "/usr/lib/X11/app-defaults"
  300. #ifndef MAXHOSTNAMELEN
  301. #define MAXHOSTNAMELEN 64
  302. #endif
  303.  
  304. static XrmDatabase dbCmd, dbApp, dbDef, dbEnv, db = (XrmDatabase)0;
  305.  
  306. char *pr_GetR(), *getenv(), *type[20];
  307. XrmValue value;
  308.  
  309. #define Nopt 25
  310. static XrmOptionDescRec options[] = {
  311.    {"-mono",             ".mono",             XrmoptionNoArg,   "on" },
  312.    {"-gray",             ".gray",             XrmoptionNoArg,   "on" },
  313.    {"-clear",            ".clear",            XrmoptionNoArg,   "on" },
  314.    {"-display",          ".display",          XrmoptionSepArg,  NULL },
  315.    {"-name",             ".name",             XrmoptionSepArg,  NULL },
  316.    {"-geometry",         "*geometry",         XrmoptionSepArg,  NULL },
  317.    {"-background",       "*background",       XrmoptionSepArg,  NULL },
  318.    {"-bg",               "*background",       XrmoptionSepArg,  NULL },
  319.    {"-foreground",       "*foreground",       XrmoptionSepArg,  NULL },
  320.    {"-fg",               "*foreground",       XrmoptionSepArg,  NULL },
  321.    {"-bordercolor",      "*bordercolor",      XrmoptionSepArg,  NULL },
  322.    {"-bd",               "*bordercolor",      XrmoptionSepArg,  NULL },
  323.    {"-borderwidth",      ".borderwidth",      XrmoptionSepArg,  NULL },
  324.    {"-bw",               ".borderwidth",      XrmoptionSepArg,  NULL },
  325.    {"-font",             "*font",             XrmoptionSepArg,  NULL },
  326.    {"-fn",               "*font",             XrmoptionSepArg,  NULL },
  327.    {"-reverse",          "*reverseVideo",     XrmoptionNoArg,   "on" },
  328.    {"-rv",               "*reverseVideo",     XrmoptionNoArg,   "on" },
  329.    {"+rv",               "*reverseVideo",     XrmoptionNoArg,   "off"},
  330.    {"-iconic",           "*iconic",           XrmoptionNoArg,   "on" },
  331.    {"-synchronous",      "*synchronous",      XrmoptionNoArg,   "on" },
  332.    {"-xnllanguage",      "*xnllanguage",      XrmoptionSepArg,  NULL },
  333.    {"-selectionTimeout", "*selectionTimeout", XrmoptionSepArg,  NULL },
  334.    {"-title",            ".title",            XrmoptionSepArg,  NULL },
  335.    {"-xrm",              NULL,                XrmoptionResArg,  NULL },
  336.    };
  337.  
  338. preset(argc, argv) int argc; char *argv[]; {
  339.    int Argc = argc; char **Argv = argv;
  340.  
  341.    char *display = getenv("DISPLAY"),  *home = getenv("HOME");
  342.    char *server_defaults, *env, buf[256];
  343.  
  344.    /*---set to ignore ^C and ^Z----------------------------------------------*/
  345.  
  346.    signal(SIGINT, SIG_IGN);
  347. #ifdef SIGTSTP
  348.    signal(SIGTSTP, SIG_IGN);
  349. #endif
  350.  
  351.    /*---prescan arguments for "-name"----------------------------------------*/
  352.  
  353.    while(++Argv, --Argc > 0) {
  354.       if (!strcmp(*Argv, "-name") && Argc > 1) {
  355.      strncpy(Name, Argv[1], 64);
  356.      strncpy(Class, Argv[1], 64);
  357.      if (Class[0] >= 'a' && Class[0] <= 'z') Class[0] -= 0x20;
  358.      }
  359.       }
  360.    Argc = argc; Argv = argv;
  361.  
  362.    /*---parse command line---------------------------------------------------*/
  363.  
  364.    XrmInitialize();
  365.    XrmParseCommand(&dbCmd, options, Nopt, Name, &Argc, Argv);
  366.    if (Argc > 1) {
  367.       fprintf(stderr, "\ngnuplot: bad option: %s\n", Argv[1]);
  368.       fprintf(stderr, "gnuplot: X11 aborted.\n");
  369.       exit(1);
  370.       }
  371.    if (pr_GetR(dbCmd, ".display")) display = value.addr;
  372.  
  373.    /*---open display---------------------------------------------------------*/
  374.  
  375.    dpy = XOpenDisplay(display); 
  376.    if (!dpy) {
  377.       fprintf(stderr, "\ngnuplot: unable to open display '%s'\n", display);
  378.       fprintf(stderr, "gnuplot: X11 aborted.\n");
  379.       exit(1);
  380.       }
  381.    scr = DefaultScreen(dpy);
  382.    vis = DefaultVisual(dpy,scr);
  383.    D = DefaultDepth(dpy,scr);
  384.    root = DefaultRootWindow(dpy);
  385.    server_defaults = XResourceManagerString(dpy);
  386.  
  387.    /*---get application defaults--(subset of Xt processing)------------------*/
  388.  
  389.    sprintf(buf, "%s/%s", AppDefDir, "Gnuplot");
  390.    dbApp = XrmGetFileDatabase(buf);
  391.    XrmMergeDatabases(dbApp, &db);
  392.  
  393.    /*---get server or ~/.Xdefaults-------------------------------------------*/
  394.  
  395.    if (server_defaults)
  396.       dbDef = XrmGetStringDatabase(server_defaults);
  397.    else {
  398.       sprintf(buf, "%s/.Xdefaults", home);
  399.       dbDef = XrmGetFileDatabase(buf);
  400.       }
  401.    XrmMergeDatabases(dbDef, &db);
  402.  
  403.    /*---get XENVIRONMENT or  ~/.Xdefaults-hostname---------------------------*/
  404.  
  405.    if (env = getenv("XENVIRONMENT")) 
  406.       dbEnv = XrmGetFileDatabase(env);
  407.    else {
  408.       char *p, host[MAXHOSTNAMELEN];
  409.       if (gethostname(host, MAXHOSTNAMELEN) < 0) {
  410.      fprintf(stderr, "gnuplot: gethostname failed. X11 aborted.\n");
  411.      exit(1);
  412.      }
  413.       if (p = index(host, '.')) *p = '\0';
  414.       sprintf(buf, "%s/.Xdefaults-%s", home, host);
  415.       dbEnv = XrmGetFileDatabase(buf);
  416.       }
  417.    XrmMergeDatabases(dbEnv, &db);
  418.  
  419.    /*---merge command line options-------------------------------------------*/
  420.  
  421.    XrmMergeDatabases(dbCmd, &db);
  422.  
  423.    /*---determine geometry, font and colors----------------------------------*/
  424.  
  425.    pr_geometry();
  426.    pr_font();
  427.    pr_color();
  428.  
  429.    /*---create window--------------------------------------------------------*/
  430.  
  431.    pr_window();
  432.  
  433.    } 
  434.  
  435. /*-----------------------------------------------------------------------------
  436.  *   pr_GetR - get resource from database using "-name" option (if any)
  437.  *---------------------------------------------------------------------------*/
  438.  
  439. char *
  440. pr_GetR(db, resource) XrmDatabase db; char *resource; {
  441.    char name[128], class[128], *rc;
  442.  
  443.    strcpy(name, Name); strcat(name, resource);
  444.    strcpy(class, Class); strcat(class, resource);
  445.    rc = XrmGetResource(db, name, class, type, &value)
  446.       ? (char *)value.addr 
  447.       : (char *)0;
  448.    return(rc);
  449.    }
  450.  
  451. /*-----------------------------------------------------------------------------
  452.  *   pr_color - determine color values
  453.  *---------------------------------------------------------------------------*/
  454.  
  455. char color_keys[Ncolors][30] =   { 
  456.    "background", "bordercolor", "text", "border", "axis", 
  457.    "line1", "line2", "line3",  "line4", 
  458.    "line5", "line6", "line7",  "line8" 
  459.    };
  460. char color_values[Ncolors][30] = { 
  461.    "white", "black",  "black",  "black",  "black", 
  462.    "red",   "green",  "blue",   "magenta", 
  463.    "cyan",  "sienna", "orange", "coral" 
  464.    };
  465. char gray_values[Ncolors][30] = { 
  466.    "black",   "white",  "white",  "gray50", "gray50",
  467.    "gray100", "gray60", "gray80", "gray40", 
  468.    "gray90",  "gray50", "gray70", "gray30" 
  469.    };
  470.  
  471. pr_color() {
  472.    unsigned long black = BlackPixel(dpy, scr), white = WhitePixel(dpy,scr);
  473.    char option[20], *v, *type = (Gray) ? "Gray" : "Color";
  474.    XColor used, exact;
  475.    Colormap cmap;
  476.    int n;
  477.  
  478.    pr_GetR(db, ".mono")         && On(value.addr) && Mono++;
  479.    pr_GetR(db, ".gray")         && On(value.addr) && Gray++;
  480.    pr_GetR(db, ".reverseVideo") && On(value.addr) && Rv++;
  481.  
  482.    if (!Gray && (vis->class == GrayScale || vis->class == StaticGray)) Mono++;
  483.  
  484.    if (!Mono) {
  485.       cmap = DefaultColormap(dpy, scr);
  486.       for (n=0; n<Ncolors; n++) {
  487.      strcpy(option, ".");
  488.      strcat(option, color_keys[n]);
  489.      (n > 1) && strcat(option, type);
  490.      v = pr_GetR(db, option) 
  491.          ? value.addr
  492.          : ((Gray) ? gray_values[n] : color_values[n]);
  493.      if (XAllocNamedColor(dpy, cmap, v, &used, &exact))
  494.         colors[n] = used.pixel;
  495.      else {
  496.         fprintf(stderr, "\ngnuplot: can't allocate %s:%s\n", option, v);
  497.         fprintf(stderr, "gnuplot: reverting to monochrome\n");
  498.         Mono++; break;
  499.         }
  500.      }
  501.       }
  502.    if (Mono) {
  503.       colors[0] = (Rv) ? black : white ;
  504.       for (n=1; n<Ncolors; n++)  colors[n] = (Rv) ? white : black;
  505.       }
  506.    }
  507.  
  508. /*-----------------------------------------------------------------------------
  509.  *   pr_font - determine font          
  510.  *---------------------------------------------------------------------------*/
  511.  
  512. pr_font() {
  513.    char *fontname = pr_GetR(db, ".font");
  514.  
  515.    if (!fontname) fontname = FallbackFont;
  516.    font = XLoadQueryFont(dpy, fontname);
  517.    if (!font) {
  518.       fprintf(stderr, "\ngnuplot: can't load font '%s'\n", fontname);
  519.       fprintf(stderr, "gnuplot: using font '%s' instead.\n", FallbackFont);
  520.       font = XLoadQueryFont(dpy, FallbackFont);
  521.       if (!font) {
  522.      fprintf(stderr, "gnuplot: can't load font '%s'\n", FallbackFont);
  523.      fprintf(stderr, "gnuplot: no useable font - X11 aborted.\n");
  524.          exit(1);
  525.      }
  526.       }
  527.    vchar = font->ascent + font->descent;
  528.    }
  529.  
  530. /*-----------------------------------------------------------------------------
  531.  *   pr_geometry - determine window geometry      
  532.  *---------------------------------------------------------------------------*/
  533.  
  534. pr_geometry() {
  535.    char *geometry = pr_GetR(db, ".geometry");
  536.    int x, y, flags;
  537.    unsigned int w, h; 
  538.  
  539.    if (geometry) {
  540.       flags = XParseGeometry(geometry, &x, &y, &w, &h);
  541.  
  542.       if (flags & WidthValue)  W = w;
  543.       if (flags & HeightValue) H = h;
  544.       if (flags & XValue) {
  545.      if (flags & XNegative) x += DisplayWidth(dpy,scr);
  546.      gX = x;
  547.      }
  548.       if (flags & YValue) {
  549.      if (flags & YNegative) y += DisplayHeight(dpy,scr);
  550.      gY = y;
  551.      }
  552.       }
  553.    }
  554.  
  555. /*-----------------------------------------------------------------------------
  556.  *   pr_window - create window 
  557.  *---------------------------------------------------------------------------*/
  558.  
  559. pr_window() {
  560.    char *title =  pr_GetR(db, ".title");
  561.    XSizeHints hints;
  562.  
  563.    win = XCreateSimpleWindow(dpy, root, gX, gY, W, H, 2, colors[1], colors[0]);
  564.  
  565.    pr_GetR(db, ".clear") && On(value.addr) && Clear++;
  566.  
  567.    hints.flags = PPosition;
  568.    hints.x = gX; hints.y = gY;
  569.    XSetNormalHints(dpy, win, &hints);
  570.  
  571.    if (pr_GetR(db, ".iconic") && On(value.addr)) {
  572.       XWMHints wmh;
  573.  
  574.       wmh.flags = StateHint ;
  575.       wmh.initial_state = IconicState;
  576.       XSetWMHints(dpy, win, &wmh);
  577.       } 
  578.  
  579.    XStoreName(dpy, win, ((title) ? title : Class));
  580.  
  581.    XSelectInput(dpy, win, StructureNotifyMask);
  582.    XMapWindow(dpy, win);
  583.    
  584.    }
  585.